package com.bestv.search.management.command;

import com.bestv.search.common.cache.SystemCache;
import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.Site;
import com.bestv.search.common.model.SysUser;
import com.bestv.search.common.model.uid.UID;
import com.bestv.search.common.service.SiteManager;
import com.bestv.search.common.util.CommandException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SiteCommand {
    protected final Log log = LogFactory.getLog(getClass());
    private SiteManager siteManager;
    private SystemCache systemCache;

    public SiteManager getSiteManager() {
        return siteManager;
    }

    public void setSiteManager(SiteManager siteManager) {
        this.siteManager = siteManager;
    }

    public SystemCache getSystemCache() {
        return systemCache;
    }

    public void setSystemCache(SystemCache systemCache) {
        this.systemCache = systemCache;
    }

    public String delete(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) {
        String[] id = (String[]) map.get("id");

        try {
            siteManager.deleteSite(dsKey, new Long(id[0]));
        } catch (NumberFormatException e) {
            log.error(e);
        } catch (CommandException e) {
            log.error(e);
            return "{'result':'success','message':'relateinfo'}";
        }
        return "{'result':'success','message':''}";
    }

    public String find(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) throws CommandException {
        String result = "";

        List<Site> sites = new ArrayList<Site>();
        if ("HDQ".equals(user.getSite().getCode())) {
            sites = siteManager.getSites(dsKey);
        } else {
            sites.clear();
            sites.add(user.getSite());
        }
        try {
            JSONArray jsonArray = sitesToJson(sites);
            result = "{'sites':" + jsonArray.toString() + "}";
        } catch (JSONException e) {
            log.error(e);
            throw new CommandException();
        }
        return result;
    }

    public String findExpHDQ(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) throws CommandException {
        String result = "";

        List<Site> sites = new ArrayList<Site>();
        if ("HDQ".equals(user.getSite().getCode())) {
            sites = siteManager.getSitesExpHDQ(dsKey);
        } else {
            sites.clear();
            sites.add(user.getSite());
        }
        try {
            JSONArray jsonArray = sitesToJson(sites);
            result = "{'sites':" + jsonArray.toString() + "}";
        } catch (JSONException e) {
            log.error(e);
            throw new CommandException();
        }
        return result;
    }

    public String get(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) throws CommandException {
        String result = "";
        String[] id = (String[]) map.get("id");

        Site site = siteManager.getSiteById(dsKey, new Long(id[0]));
        try {
            JSONObject jobj = siteToJson(site);
            result = jobj.toString();
        } catch (JSONException e) {
            log.error(e);
        }
        return result;
    }

    public String save(SysUser user, Map<String, String[]> map, DataSourceKey dsKey) {
        String result = "";
        String[] id = map.get("id");
        String[] code = map.get("siteCode");

        String[] name = map.get("siteName");
        Site newsite = null;
        if ("".equals(id[0])) {
            // new
            Site site = siteManager.getSiteByCode(dsKey, code[0]);
            if (site != null)
                return "{'result':'failure','message':'code'}";
            site = siteManager.getSiteByName(dsKey, name[0]);
            if (site != null)
                return "{'result':'failure','message':'name'}";
            newsite = new Site();
            newsite.setCode(code[0]);
            newsite.setName(name[0]);
            newsite.setId(new Long(UID.getUID(newsite)));
            siteManager.saveSite(dsKey, newsite);
            result = "{'result':'success','message':'new'}";
        } else {
            newsite = siteManager.getSiteById(dsKey, new Long(id[0]));
            newsite.setCode(code[0]);
            newsite.setName(name[0]);
            siteManager.saveSite(dsKey, newsite);
            result = "{'result':'success','message':'edit'}";
        }
        return result;
    }

    /**
     * Gets managed sites list by MgmtDataSourceKey from local site
     *
     * @param user
     * @param map
     * @param dsKey
     * @return
     */
    public String getMgmtSitesToJson(SysUser user, Map<String, String[]> map, DataSourceKey dsKsey) {
        int size = systemCache.getMgmtDataSourceKeyList() == null ? 0 : systemCache.getMgmtDataSourceKeyList().size();
        String[] siteCodes = new String[size + 1];

        // local dataSourceKey equals to local site code.
        siteCodes[0] = systemCache.getLocalDataSourceKey();
        // MgmtDataSourceKey equals siteCode
        for (int i = 1; i <= size; i++) {
            siteCodes[i] = systemCache.getMgmtDataSourceKeyList().get(i - 1);
        }

        List<Site> sites = siteManager.getSitesByCodes(DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey()),
                siteCodes);
        String result = null;
        try {
            JSONArray jsonArray = sitesToJson(sites);
            result = jsonArray.toString();
        } catch (JSONException e) {
            log.error(e);
        }

        return "{'sites':" + result + "}";
    }

    private JSONObject siteToJson(Site site) throws JSONException {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id", site.getId());
        jsonObject.put("name", site.getName());
        jsonObject.put("code", site.getCode());
        return jsonObject;
    }

    private JSONArray sitesToJson(List<Site> sites) throws JSONException {
        List<JSONObject> list = new ArrayList<JSONObject>();
        for (Site site : sites) {
            list.add(siteToJson(site));
        }
        JSONArray jsonArray = new JSONArray(list.toArray());
        return jsonArray;
    }
}
